/**
 * videojs-http-source-selector
 * @version 1.1.6
 * @copyright 2019 Justin Fujita <Justin@pivotshare.com>
 * @license MIT
 */
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('video.js')) :
        typeof define === 'function' && define.amd ? define(['video.js'], factory) :
            (global = global || self, global['videojs-http-source-selector'] = factory(global.videojs));
}(this, function (videojs) {
    'use strict';

    videojs = videojs && videojs.hasOwnProperty('default') ? videojs['default'] : videojs;

    var version = "1.1.6";

    function _inheritsLoose(subClass, superClass) {
        subClass.prototype = Object.create(superClass.prototype);
        subClass.prototype.constructor = subClass;
        subClass.__proto__ = superClass;
    }

    function _assertThisInitialized(self) {
        if (self === void 0) {
            throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
        }

        return self;
    }

    var MenuItem = videojs.getComponent('MenuItem');
    var Component = videojs.getComponent('Component');

    var SourceMenuItem =
        /*#__PURE__*/
        function (_MenuItem) {
            _inheritsLoose(SourceMenuItem, _MenuItem);

            function SourceMenuItem(player, options) {
                options.selectable = true;
                options.multiSelectable = false;
                return _MenuItem.call(this, player, options) || this;
            }

            var _proto = SourceMenuItem.prototype;

            _proto.handleClick = function handleClick() {
                var selected = this.options_;
                console.log("Changing quality to:", selected.label);

                _MenuItem.prototype.handleClick.call(this);

                var levels = this.player().qualityLevels();

                for (var i = 0; i < levels.length; i++) {
                    if (selected.index == levels.length) {
                        // If this is the Auto option, enable all renditions for adaptive selection
                        levels[i].enabled = true;
                    } else if (selected.index == i) {
                        levels[i].enabled = true;
                    } else {
                        levels[i].enabled = false;
                    }
                }
            };

            _proto.update = function update() {
                var selectedIndex = this.player().qualityLevels().selectedIndex;
                this.selected(this.options_.index == selectedIndex);
            };

            return SourceMenuItem;
        }(MenuItem);

    Component.registerComponent('SourceMenuItem', SourceMenuItem);

    var MenuButton = videojs.getComponent('MenuButton');

    var SourceMenuButton =
        /*#__PURE__*/
        function (_MenuButton) {
            _inheritsLoose(SourceMenuButton, _MenuButton);

            function SourceMenuButton(player, options) {
                var _this;

                _this = _MenuButton.call(this, player, options) || this;
                MenuButton.apply(_assertThisInitialized(_this), arguments);

                var qualityLevels = _this.player().qualityLevels(); // Handle options: We accept an options.default value of ( high || low )
                // This determines a bias to set initial resolution selection.


                if (options && options["default"]) {
                    if (options["default"] == 'low') {
                        for (var i = 0; i < qualityLevels.length; i++) {
                            qualityLevels[i].enabled = i == 0;
                        }
                    } else if (options["default"] = 'high') {
                        for (var i = 0; i < qualityLevels.length; i++) {
                            qualityLevels[i].enabled = i == qualityLevels.length - 1;
                        }
                    }
                } // Bind update to qualityLevels changes


                _this.player().qualityLevels().on(['change', 'addqualitylevel'], videojs.bind(_assertThisInitialized(_this), _this.update));

                return _this;
            }

            var _proto = SourceMenuButton.prototype;

            _proto.createEl = function createEl() {
                return videojs.dom.createEl('div', {
                    className: 'vjs-http-source-selector vjs-menu-button vjs-menu-button-popup vjs-control vjs-button'
                });
            };

            _proto.buildCSSClass = function buildCSSClass() {
                return MenuButton.prototype.buildCSSClass.call(this) + ' vjs-icon-cog';
            };

            _proto.update = function update() {
                return MenuButton.prototype.update.call(this);
            };

            _proto.createItems = function createItems() {
                var menuItems = [];
                var levels = this.player().qualityLevels();
                var labels = [];

                for (var i = 0; i < levels.length; i++) {
                    var index = levels.length - (i + 1);
                    var selected = index === levels.selectedIndex; // Display height if height metadata is provided with the stream, else use bitrate

                    var label = "" + index;
                    var sortVal = index;

                    if (levels[index].height) {
                        label = levels[index].height + "p";
                        sortVal = parseInt(levels[index].height, 10);
                    } else if (levels[index].bitrate) {
                        label = Math.floor(levels[index].bitrate / 1e3) + " kbps";
                        sortVal = parseInt(levels[index].bitrate, 10);
                    } // Skip duplicate labels


                    if (labels.indexOf(label) >= 0) {
                        continue;
                    }

                    labels.push(label);
                    menuItems.push(new SourceMenuItem(this.player_, {
                        label: label,
                        index: index,
                        selected: selected,
                        sortVal: sortVal
                    }));
                } // If there are multiple quality levels, offer an 'auto' option


                if (levels.length > 1) {
                    menuItems.push(new SourceMenuItem(this.player_, {
                        label: 'Auto',
                        index: levels.length,
                        selected: false,
                        sortVal: 99999
                    }));
                } // Sort menu items by their label name with Auto always first


                menuItems.sort(function (a, b) {
                    if (a.options_.sortVal < b.options_.sortVal) {
                        return 1;
                    } else if (a.options_.sortVal > b.options_.sortVal) {
                        return -1;
                    } else {
                        return 0;
                    }
                });
                return menuItems;
            };

            return SourceMenuButton;
        }(MenuButton);

    var defaults = {}; // Cross-compatibility for Video.js 5 and 6.

    var registerPlugin = videojs.registerPlugin || videojs.plugin; // const dom = videojs.dom || videojs;

    /**
    * Function to invoke when the player is ready.
    *
    * This is a great place for your plugin to initialize itself. When this
    * function is called, the player will have its DOM and child components
    * in place.
    *
    * @function onPlayerReady
    * @param    {Player} player
    *           A Video.js player object.
    *
    * @param    {Object} [options={}]
    *           A plain object containing options for the plugin.
    */

    var onPlayerReady = function onPlayerReady(player, options) {
        player.addClass('vjs-http-source-selector');
        console.log("videojs-http-source-selector initialized!");
        console.log("player.techName_:" + player.techName_); //This plugin only supports level selection for HLS playback

        if (player.techName_ != 'Html5') {
            return false;
        }
        /**
        *
        * We have to wait for the manifest to load before we can scan renditions for resolutions/bitrates to populate selections
        *
        **/


        player.on(['loadedmetadata'], function (e) {
            var qualityLevels = player.qualityLevels();
            videojs.log('loadmetadata event'); // hack for plugin idempodency... prevents duplicate menubuttons from being inserted into the player if multiple player.httpSourceSelector() functions called.

            if (player.videojs_http_source_selector_initialized == 'undefined' || player.videojs_http_source_selector_initialized == true) {
                console.log("player.videojs_http_source_selector_initialized == true");
            } else {
                console.log("player.videojs_http_source_selector_initialized == false");
                player.videojs_http_source_selector_initialized = true;
                var controlBar = player.controlBar,
                    fullscreenToggle = controlBar.getChild('fullscreenToggle').el();
                controlBar.el().insertBefore(controlBar.addChild('SourceMenuButton').el(), fullscreenToggle);
            }
        });
    };
    /**
    * A video.js plugin.
    *
    * In the plugin function, the value of `this` is a video.js `Player`
    * instance. You cannot rely on the player being in a "ready" state here,
    * depending on how the plugin is invoked. This may or may not be important
    * to you; if not, remove the wait for "ready"!
    *
    * @function httpSourceSelector
    * @param    {Object} [options={}]
    *           An object of options left to the plugin author to define.
    */


    var httpSourceSelector = function httpSourceSelector(options) {
        var _this = this;

        this.ready(function () {
            onPlayerReady(_this, videojs.mergeOptions(defaults, options)); //this.getChild('controlBar').addChild('SourceMenuButton', {});
        });
        videojs.registerComponent('SourceMenuButton', SourceMenuButton);
        videojs.registerComponent('SourceMenuItem', SourceMenuItem);
    }; // Register the plugin with video.js.


    registerPlugin('httpSourceSelector', httpSourceSelector); // Include the version number.

    httpSourceSelector.VERSION = version;

    return httpSourceSelector;

}));